﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;
using Models;
using Common;

namespace BLL
{
    public class WorkflowManager
    {
        private WorkflowService objWorkflowService = new WorkflowService();
        private UserInfoService objUserInfoService = new UserInfoService();
        /// <summary>
        /// 查找用户有权限创建的工作流
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public List<UserTeamRole> GetUserCreateWorkflow(string userName)
        {
            return objWorkflowService.GetUserCreateWorkflow(userName);
        }

        /// <summary>
        /// 根据ID查找模板主从表信息
        /// </summary>
        /// <param name="workParentId"></param>
        /// <returns></returns>
        public void GetWorkflowMould(int workParentId, out WorkflowMould workMould, out List<WorkflowChildMould> workChildMould)
        {
            workMould = objWorkflowService.GetParentWorkflowMould(workParentId);
            workChildMould = new List<WorkflowChildMould>(objWorkflowService.GetChildWorkflowMould(workParentId));
        }
        /// <summary>
        /// 新增一条工作流
        /// </summary>
        /// <param name="workMould"></param>
        /// <param name="workChildMould"></param>
        /// <param name="userName"></param>
        /// <param name="createrTeamId"></param>
        /// <returns></returns>
        public bool InsertWorkflow(WorkflowMould workMould, List<WorkflowChildMould> workChildMould, string userName, int createrTeamId, string critical, string content)
        {
            int parentId = objWorkflowService.InsertWorkflowStatuses(workMould, userName, createrTeamId, critical, content);
            try
            {
                //创建子工作流，如果TeamId=0，则改为创建者TeamId
                objWorkflowService.InsertWorkflowChildStatus(workChildMould, parentId, createrTeamId);
                return true;
            }
            catch (Exception ex)
            {
                objWorkflowService.DeleteWorkflowStatus(parentId);
                string throwException = "新增工作流错误" + ex.Message;
                throw new Exception(throwException);
            }

        }
        /// <summary>
        /// 根据用户名、状态查询工作流主表
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="StatusDefine"></param>
        /// <returns></returns>
        public List<WorkflowStatus> GetWorkflowStatus(string userName, int statusDefine)
        {
            return objWorkflowService.GetWorkflowStatus(userName, statusDefine);
        }
        /// <summary>
        /// 根据Id号 更改工作流状态
        /// </summary>
        /// <param name="workflowParentId"></param>
        /// <param name="statusDefine"></param>
        /// <param name="statusNo"></param>
        /// <returns></returns>
        public int UpdateWorkflowStatus(int workflowParentId, int statusDefine, int statusNo)
        {
            return objWorkflowService.UpdateWorkflowStatus(workflowParentId, statusDefine, statusNo);
        }
        /// <summary>
        /// 根据Id号 更改工作流状态
        /// </summary>
        /// <param name="workflowParentId"></param>
        /// <param name="statusDefine"></param>
        /// <param name="statusNo"></param>
        /// <returns></returns>
        public int UpdateWorkflowStatus(int workflowParentId, int statusDefine)
        {
            return objWorkflowService.UpdateWorkflowStatus(workflowParentId, statusDefine);
        }
        /// <summary>
        /// 根据状态主表id和节点号查询子表
        /// </summary>
        /// <param name="workParentId"></param>
        /// <param name="nodeNo"></param>
        /// <returns></returns>
        public List<WorkflowChildStatus> GetWorkflowChildStatus(int workParentId, int nodeNo)
        {
            return objWorkflowService.GetWorkflowChildStatus(workParentId, nodeNo);
        }




        /// <summary>
        /// 根据用户名查找需要审批的工作流
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public List<WorkflowStatus> GetWorkflowStatus(string userName)
        {
            return (from c in objWorkflowService.GetWorkflowStatus(userName) where (c.ChildStatusNo == 1 || c.ChildStatusNo == -1) && c.StatusDefine != -2 orderby c.IsRead  select c).ToList();

        }
        /// <summary>
        /// 更新工作流状态（退回）
        /// </summary>
        /// <param name="objWorkflowChild"></param>
        /// <param name="objWorkflow"></param>
        public void ReturnWorkflow(int workChildId, int workParentId,string returnReason)
        {
            WorkflowStatus objWorkflow = objWorkflowService.GetWorkflowStatus(workParentId);
            WorkflowChildStatus objWorkflowChild = objWorkflowService.GetWorkflowChildStatus(workChildId);
            objWorkflow.StatusNo = objWorkflow.StatusNo - 1;
            if (objWorkflow.StatusNo == 0)
            {
                objWorkflow.StatusDefine = 0;
            }
            //更新主表
            objWorkflowService.UpdateWorkflowStatus(objWorkflow.WorkParentId, objWorkflow.StatusDefine, objWorkflow.StatusNo);
            //更新本节点
            objWorkflowService.UpdateWorkflowChildStatus(0, objWorkflowChild.WorkChildId);
            
            //更新上一节点（判断有没有上一节点）
            if (objWorkflowChild.NodeNo != 1)
            {
                List<WorkflowChildStatus> listPrevWorkflowChild = objWorkflowService.GetWorkflowChildStatus(objWorkflowChild.WorkParentId, objWorkflowChild.NodeNo - 1);
                foreach (var item in listPrevWorkflowChild)
                {
                    item.StatusNo = 1;
                    objWorkflowService.UpdateWorkflowChildStatus(item);
                    UpadteReturnReason(item.WorkChildId, returnReason);
                    UserInfo fromUser = objUserInfoService.GetUserInfo(objWorkflowChild.UserName);
                    UserInfo toUser = objUserInfoService.GetUserInfo(item.UserName);
                    ExchangeSendMail.SendNoFile(fromUser.Email, fromUser.UserName, toUser.Email, "工作任务退回", objWorkflow.Content + "<br/>" + fromUser.DisplayName + "退回该工作流，请重新处理");
                }
            }
            else
            {
                UpadteParentReturnReason(objWorkflow.WorkParentId, returnReason);
                UserInfo fromUser = objUserInfoService.GetUserInfo(objWorkflowChild.UserName);
                UserInfo toUser = objUserInfoService.GetUserInfo(objWorkflow.CreaterUserName);
                ExchangeSendMail.SendNoFile(fromUser.Email, fromUser.UserName, toUser.Email, "工作任务退回", objWorkflow.Content + "<br/>" + fromUser.DisplayName + "退回该工作流，请重新处理");
            }
        }
        /// <summary>
        /// 更新工作流状态（暂停）
        /// </summary>
        /// <param name="objWorkflowChild"></param>
        /// <param name="objWorkflow"></param>
        public void PauseWorkflow(int workChildId, int workParentId)
        {
            WorkflowStatus objWorkflow = objWorkflowService.GetWorkflowStatus(workParentId);
            WorkflowChildStatus objWorkflowChild = objWorkflowService.GetWorkflowChildStatus(workChildId);
            //更新主表
            objWorkflowService.UpdateWorkflowStatus(workParentId, -1);
            //更新本节点
            objWorkflowService.UpdateWorkflowChildStatus(-1, workChildId);

            UserInfo fromUser = objUserInfoService.GetUserInfo(objWorkflowChild.UserName);
            UserInfo toUser = objUserInfoService.GetUserInfo(objWorkflow.CreaterUserName);
            ExchangeSendMail.SendNoFile(fromUser.Email, fromUser.UserName, toUser.Email, "工作任务暂停", objWorkflow.Content + "<br/>" + fromUser.DisplayName + "暂停该工作流，请联系处理");

        }

        #region 更新工作流 pass
        /// <summary>
        /// 更新工作流信息(提交、pass)  需指定下一节点关键用户
        /// </summary>
        /// <param name="workParentId"></param>
        /// <param name="nodeNo">下一节点序号</param>
        /// <param name="childNodeNo"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public void UpdateWorkflowStatus(string userName, WorkflowChildStatus objNextWorkflowChild)
        {
            WorkflowStatus objNowWorkflow = objWorkflowService.GetWorkflowStatus(objNextWorkflowChild.WorkParentId);

            //1.判断是否是创建节点
            if (objNextWorkflowChild.NodeNo == 1)
            {
                //是 更新主表状态
                objWorkflowService.UpdateWorkflowStatus(objNextWorkflowChild.WorkParentId, 1, 1);
                //更新下一节点子表状态
                objWorkflowService.UpdateWorkflowChildStatus(userName, objNextWorkflowChild);
                //邮件推送
                UserInfo fromUser = objUserInfoService.GetUserInfo(objNowWorkflow.CreaterUserName);
                UserInfo toUser = objUserInfoService.GetUserInfo(userName);
                ExchangeSendMail.SendNoFile(fromUser.Email, fromUser.UserName, toUser.Email, "工作任务推送", objNowWorkflow.Content + "<br/>" + "收到新的工作流，请及时处理");
                // 日志更新
                InsertWorkflowLog(objNowWorkflow.WorkParentId, 0, fromUser.DisplayName, "Submit", "");

            }
            //2.判断是否是最后一个节点(最后一个节点一定是单节点)
            else if (objNowWorkflow.NodeCount == objNowWorkflow.StatusNo)
            {
                WorkflowChildStatus objNowWorkflowChild = objWorkflowService.GetWorkflowChildStatus(objNextWorkflowChild.WorkParentId, objNextWorkflowChild.NodeNo - 1, 1);
                objNowWorkflowChild.StatusNo = 100;
                //是 更新主表状态
                objWorkflowService.UpdateWorkflowStatus(objNextWorkflowChild.WorkParentId, 100, 100);
                //更新本节点子表状态
                objWorkflowService.UpdateWorkflowChildStatus(objNowWorkflowChild);
                //日志更新
                UserInfo User = objUserInfoService.GetUserInfo(objNowWorkflowChild.UserName);
                InsertWorkflowLog(objNowWorkflowChild.WorkParentId, objNowWorkflowChild.WorkChildId, User.DisplayName, "Pass", "");
            }
            else//不是最后的节点
            {
                List<WorkflowChildStatus> childList = GetWorkflowChildStatus(objNextWorkflowChild.WorkParentId, objNextWorkflowChild.NodeNo - 1);
                WorkflowChildStatus objNowWorkflowChild = objWorkflowService.GetWorkflowChildStatus(objNextWorkflowChild.WorkParentId, objNextWorkflowChild.NodeNo - 1, 1);
                objNowWorkflowChild.StatusNo = 100;
                if (childList.Count == 1)//判断本节点是否是单节点
                {
                    objWorkflowService.UpdateWorkflowStatus(objNextWorkflowChild.WorkParentId, 1, objNowWorkflow.StatusNo + 1);
                    objWorkflowService.UpdateWorkflowChildStatus(objNowWorkflowChild);
                    objWorkflowService.UpdateWorkflowChildStatus(userName, objNextWorkflowChild);
                    UserInfo fromUser = objUserInfoService.GetUserInfo(objNowWorkflowChild.UserName);
                    UserInfo toUser = objUserInfoService.GetUserInfo(userName);
                    ExchangeSendMail.SendNoFile(fromUser.Email, fromUser.UserName, toUser.Email, "工作任务推送", objNowWorkflow.Content + "<br/>" + "收到新的工作流，请及时处理");
                    InsertWorkflowLog(objNowWorkflowChild.WorkParentId, objNowWorkflowChild.WorkChildId, fromUser.DisplayName, "Pass", "");

                }
                else//多节点
                {
                    objWorkflowService.UpdateWorkflowChildStatus(objNowWorkflowChild);
                    childList = GetWorkflowChildStatus(objNowWorkflowChild.WorkParentId, objNowWorkflowChild.NodeNo);
                    int count = (from c in childList where c.StatusNo == 100 select c).Count();
                    if (count == childList.Count)//子节点状态是否都已完成
                    {
                        objWorkflowService.UpdateWorkflowStatus(objNowWorkflow.WorkParentId, 1, objNowWorkflow.StatusNo + 1);
                        objWorkflowService.UpdateWorkflowChildStatus(userName, objNextWorkflowChild);
                        UserInfo fromUser = objUserInfoService.GetUserInfo(objNowWorkflowChild.UserName);
                        UserInfo toUser = objUserInfoService.GetUserInfo(userName);
                        ExchangeSendMail.SendNoFile(fromUser.Email, fromUser.UserName, toUser.Email, "工作任务推送", objNowWorkflow.Content + "<br/>" + "收到新的工作流，请及时处理");
                        InsertWorkflowLog(objNowWorkflowChild.WorkParentId, objNowWorkflowChild.WorkChildId, fromUser.DisplayName, "Pass", "");
                    }
                    else
                    {
                        UserInfo fromUser = objUserInfoService.GetUserInfo(objNowWorkflowChild.UserName);
                        objWorkflowService.UpdateWorkflowChildStatusUserName(userName, objNextWorkflowChild);
                        InsertWorkflowLog(objNowWorkflowChild.WorkParentId, objNowWorkflowChild.WorkChildId, fromUser.DisplayName, "Pass", "");
                    }
                }
            }
        }

        /// <summary>
        /// 更新工作流信息(pass) 不需要指定下一节点用户
        /// </summary>
        /// <param name="objWorkflowChild"></param>
        public void UpdateWorkflowStatus(WorkflowChildStatus objWorkflowChild)
        {
            WorkflowStatus objNowWorkflow = objWorkflowService.GetWorkflowStatus(objWorkflowChild.WorkParentId);

            //更新本节点子表状态
            objWorkflowService.UpdateWorkflowChildStatus(100, objWorkflowChild.WorkChildId);
            //1.判断是否是最后一个pass
            List<WorkflowChildStatus> childList = GetWorkflowChildStatus(objWorkflowChild.WorkParentId, objNowWorkflow.StatusNo);
            int count = (from c in childList where c.StatusNo == 100 select c).Count();
            if (count == childList.Count)//最后一个pass
            {
                //2.判断是否是最后一个节点(最后一个节点一定是单节点)
                if (objNowWorkflow.NodeCount == objNowWorkflow.StatusNo)
                {
                    //更新主表状态
                    objWorkflowService.UpdateWorkflowStatus(objNowWorkflow.WorkParentId, 100, 100);
                    //日志更新
                    WorkflowChildStatus objNowWorkflowChildStatus = objWorkflowService.GetWorkflowChildStatus(objWorkflowChild.WorkChildId);
                    UserInfo fromUser = objUserInfoService.GetUserInfo(objNowWorkflowChildStatus.UserName);
                    InsertWorkflowLog(objNowWorkflowChildStatus.WorkParentId, objNowWorkflowChildStatus.WorkChildId, fromUser.DisplayName, "Pass", "");
                }
                else//非最后一个节点
                {
                    //更新主表状态
                    objWorkflowService.UpdateWorkflowStatus(objNowWorkflow.WorkParentId, 1, objNowWorkflow.StatusNo + 1);
                    //更新下一节点状态
                    objWorkflowChild.NodeNo = objNowWorkflow.StatusNo + 1;
                    objWorkflowChild.StatusNo = 1;
                    objWorkflowService.UpdateAllWorkflowChildStatus(objWorkflowChild);

                    //邮件推送
                    List<WorkflowChildStatus> listNextWorkflowChild = objWorkflowService.GetWorkflowChildStatus(objNowWorkflow.WorkParentId, objWorkflowChild.NodeNo);
                    WorkflowChildStatus objNowWorkflowChildStatus = objWorkflowService.GetWorkflowChildStatus(objWorkflowChild.WorkChildId);
                    UserInfo fromUser = objUserInfoService.GetUserInfo(objNowWorkflowChildStatus.UserName);
                    foreach (var item in listNextWorkflowChild)
                    {
                        
                        UserInfo toUser = objUserInfoService.GetUserInfo(item.UserName);
                        ExchangeSendMail.SendNoFile(fromUser.Email, fromUser.UserName, toUser.Email, "工作任务推送", objNowWorkflow.Content + "<br/>" + "收到新的工作流，请及时处理");
                    }
                    InsertWorkflowLog(objNowWorkflowChildStatus.WorkParentId, objNowWorkflowChildStatus.WorkChildId, fromUser.DisplayName, "Pass", "");
                    
                }
            }

        }
        #endregion


        /// <summary>
        /// 更新为已读
        /// </summary>
        /// <param name="workParentId"></param>
        /// <returns></returns>
        public int UpdateWorkflowChildRead(int workChildId)
        {
            return objWorkflowService.UpdateWorkflowChildRead(workChildId);
        }
        /// <summary>
        /// 子表退回原因
        /// </summary>
        /// <param name="workChildId"></param>
        /// <param name="returnReason"></param>
        /// <returns></returns>
        public int UpadteReturnReason(int workChildId, string returnReason)
        {
            return objWorkflowService.UpdateReturnReason(workChildId, returnReason);
        }
        /// <summary>
        /// 主表退回原因
        /// </summary>
        /// <param name="workParentId"></param>
        /// <param name="returnReason"></param>
        /// <returns></returns>
        public int UpadteParentReturnReason(int workParentId, string returnReason)
        {
            return objWorkflowService.UpdateParentReturnReason(workParentId, returnReason);
        }

        /// <summary>
        /// 查找点击暂停用户的姓名
        /// </summary>
        /// <param name="workParentId"></param>
        /// <returns></returns>
        public string GetPauseName(int workParentId)
        {
            List<string> list = objWorkflowService.GetPauseName(workParentId);
            string str="";
            foreach (var item in list)
            {
                str = str + item + " ";
            }
            return str;
        }
        /// <summary>
        /// 查询节点名称
        /// </summary>
        /// <param name="workParentId"></param>
        /// <returns></returns>
        public List<string> GetNodeName(int workParentId)
        {
            return objWorkflowService.GetNodeName(workParentId);
        }
         /// <summary>
        /// 根据工作流号查询工作流当前状态
        /// </summary>
        /// <param name="workParentId"></param>
        /// <returns></returns>
        public int GetWorkflowStatues(int workParentId)
        {
            return objWorkflowService.GetWorkflowStatues(workParentId);
        }
        #region 日志
        /// </summary>
        /// <param name="workflow"></param>
        /// <param name="userName"></param>
        /// <param name="type1"></param>
        /// <returns></returns>
        public int InsertWorkflowLog(int workParentId, int workflowChild, string displayName, string type1,string reason)
        {
            return objWorkflowService.InsertWorkflowLog(workParentId, workflowChild, displayName, type1, reason);
        }
        #endregion
    }
}
